package com.hmdp.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.hmdp.dto.Result;
import com.hmdp.entity.ShopType;
import com.hmdp.mapper.ShopTypeMapper;
import com.hmdp.service.IShopTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.hmdp.utils.RedisConstants.SHOP_TYPE_KEY;
import static com.hmdp.utils.RedisConstants.SHOP_TYPE_TTL;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Service
public class ShopTypeServiceImpl extends ServiceImpl<ShopTypeMapper, ShopType> implements IShopTypeService {
    private final StringRedisTemplate stringRedisTemplate;

    public ShopTypeServiceImpl(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public Result queryList() {

//        1 从redis中查询列表是否存在，获取得到String类型的列表
//        range(SHOP_TYPE_KEY, 0, -1)代表以SHOP_TYPE_KEY为Key，从第一个开始查找（0），查找到最后一个（-1），默认返回类型为String
        List<String> shopTypes_String = stringRedisTemplate.opsForList().range(SHOP_TYPE_KEY, 0, -1);
        //        2 缓存存在 转为ShopType类型的列表返回
        //          利用流操作，将String类型的列表转换为流对象
        //          对流中的每个 JSON 字符串（type）进行映射操作，将其转换为 ShopType 对象。
        //          将流中的 ShopType 对象收集到一个新的列表中
        if (!shopTypes_String.isEmpty()) {
            List<ShopType> shopTypes_ShopType = shopTypes_String.stream()
                    .map(type -> JSONUtil.toBean(type, ShopType.class))
                    .collect(Collectors.toList());
            return Result.ok(shopTypes_ShopType);
        }
//        3 缓存不存在 查询数据库中的列表信息
        List<ShopType> shopTypes_ShopType = query().orderByAsc("sort").list();
//        4 数据库中不存在 返回错误
        if (shopTypes_ShopType == null) {
            return Result.fail("店铺不存在");
        }
//        5 数据库中存在 写入到redis中
        shopTypes_String = shopTypes_ShopType.stream()
                .map(type -> JSONUtil.toJsonStr(type))
                .collect(Collectors.toList());
        stringRedisTemplate.opsForList().leftPushAll(SHOP_TYPE_KEY, shopTypes_String);
        stringRedisTemplate.expire(SHOP_TYPE_KEY, SHOP_TYPE_TTL, TimeUnit.MINUTES);
//        6 返回
        return Result.ok(shopTypes_ShopType);
    }
}
